/*
* Best PageLayer 用于控制鼠标点击来切换页面上的层次展现
* method:
* addLayer: 用于添加新显示层 
* 	options有效参数如下：
* 		layerID: 层id,唯一标示该层
* 		oneLayer: 只是该层再被创建时是否是唯一显示
* 		openFunc: 显示新层时用户回调函数
* 		openParam: 显示新层时用户回调函数参数对象
* 		closeFunc: 关闭层时用户回调函数
* 		closeParam: 关闭层时用户回调函数参数对象
*  		zIndex: 层在页面上的逻辑层次关系,层次越高该值越大
* removeLayer：去除某一显示层
* 	layerID： 层id,唯一标示该层 OR 为0时标示去除所有的显示层
* unControlLayer: 移除对某一显示层的控制, 但是该显示层的显示和隐藏做调整
* controlLayer: 重新对某一显示层进行控制, 但是该显示层的显示和隐藏做调整
*/

if (Best==undefined){
	var Best={};
}

Best.PageLayer = Class.create();
Best.PageLayer.prototype = {
	initialize: function(){
		this.register();
		this.layers = [];
		this.freezeLayer=[];
	},
	
	addLayer: function(options){
		var	options = Object.extend({
				layerID: false,
				oneLayer: false,
				openFunc: Prototype.emptyFunction,
				openParam: null,
			 	closeFunc: Prototype.emptyFunction,
			 	closeParam: null,
			 	zIndex: 0,
			 	stopEvent: true,  //创建新层时是否要忽略在document上的click事件
			 	isCloseOnSelfClick: false  //当事件的src来自当前的已有层时是否关闭已有层
			 	}, options);
		// 去除重复的层
		this.removeLayer(options.layerID);
		if (options.oneLayer)
			this._hiddenAllLayers();
		this.layers.push(options);
		this._showOneLayer(options);
	},
	
	removeLayer: function(layerID){
		if (layerID!=0){
			var iteraotr = this._hiddenOneLayer.bind(this);
			try{
				this.layers = this.layers.reject(function(e){
					if (e.layerID==layerID)
						iteraotr(e);
					return e.layerID==layerID});
				// 阻止document上的click事件关闭其他的显示层
				this.layers.each(function(e){e.stopEvent=true});
			}catch(e){};
		}
		else
			this._hiddenAllLayers();
	},
	
	controlLayer: function(layerID){
		var layers = this.layers;
		// 充非控制队列中加入到控制队列中
		this.freezeLayer = this.freezeLayer.reject(function(e){
			if (e.layerID==layerID)
				layers.push(e);
			return e.layerID==layerID;});
		// 阻止document上的click事件关闭其他的显示层
		this.layers.each(function(e){e.stopEvent=true});
	},
	
	unControlLayer: function(layerID){
		var	freezeLayer = this.freezeLayer;
		this.layers = this.layers.reject(function(e){
				if (e.layerID==layerID)
					freezeLayer.push(e);	// 加入到非控制队列中去
				return e.layerID==layerID});
		// 阻止document上的click事件关闭其他的显示层				
		this.layers.each(function(e){e.stopEvent=true});				
	},
	
	removeAllLayer: function(){
		this.removeLayer(0);
	},
	finishAddLayer: function(){
		this.layers.each(function(e){e.stopEvent=false});
	},
	register: function(){
		this._register4Doc();
	},
	
	_register4Doc: function(){
		Event.observe(document, "click", this._clickOnDoc.bind(this));
	},
	
	_clickOnDoc: function(event){
		// 创建的新层时不用处理document上的click
		var temp = this.layers.select(function(e){
				return e.stopEvent});
		if (temp.length!=0){
			this.layers.each(function(e){e.stopEvent=false});
			Event.stop(event);
			return false;
		}
		// 检查事件的src是否是来自当前的已有层
		var element = Event.element(event);
		var	onLayer = false;

		while(element!=document.body){
			temp = this.layers.select(function(e){ 
					if (element.id==undefined)
						return false;
					return e.layerID == element.id && !e.isCloseOnSelfClick});
			if (temp.length!=0){
				onLayer = true;
				break;
			}					
			element = element.parentNode;
			if(element == null||element == undefined)
				break;
		}
		// 不是来自已有层，则清空这些层
		if (!onLayer)
			this._hiddenAllLayers();
		else{ // 否则只保留显示事件源头的层
			var iteraotr = this._hiddenOneLayer.bind(this);
			this.layers.each(function(e){
				if (e.zIndex>temp[0].zIndex)	// 关闭在zIndex上大于自身的层
					iteraotr(e);
			});
		}
	},
	
	_hiddenAllLayers: function(){
		try{
			this.layers.each(function(e){
					Element.setStyle(e.layerID, {display: 'none'});
				e.closeFunc(e.closeParam);
			});
		}catch(e){}
		this.layers.clear();		
	},
	
	_hiddenOneLayer: function(e){
		try{
			if(!!$(e.layerId)){
				Element.setStyle(e.layerID, {display: 'none'});
			}
		}catch(e){};
		e.closeFunc(e.closeParam);
	},
	
	_showOneLayer: function(e){
		try{
			Element.setStyle(e.layerID, {display: ''});
			e.openFunc(e.openParam);
		}catch(e){
			
		}
	}
}

//Class-------------ResizeObserver -------------------
Best.ResizeObserver = Class.create();
Best.ResizeObserver.prototype = {
	initialize: function(){		
	 },
	layerList:new Array(),
	addListener: function(srcId,referId,xoff){
		var lsn = new Object();
		lsn.element = srcId;
  		lsn.refer = referId;  	
  		if(xoff!=null&&xoff!=undefined)	
  			lsn.xoff = xoff;  	
  		else
  			lsn.xoff =0;	  		
  		this.removeListener(src);  		
		this.layerList.push(lsn);
	},
	onResize: function() {
		for(var i = 0 ;i< this.layerList.length; i++)
		{
			var src = $(this.layerList[i].element);
			var ref = $(this.layerList[i].refer);
			
			if(src!=undefined && src!=null && ref!=undefined && ref!=null)	{
				src.style.left = (Position.cumulativeOffset(ref)[0] + this.layerList[i].xoff) + 'px';			
			}
		}
	},
	removeListener:function(src){
		this.layerList = this.layerList.reject(function(e){ 
  			return e.element.id == src.id;
  		});
	}
}
